package com.android.monee.view.activity;

import java.util.List;
import java.util.Map;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ExpandableListView;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.android.monee.data.access.DaoListener;
import com.android.monee.data.access.SimpleDaoListener;
import com.android.monee.data.model.Budget;
import com.android.monee.data.model.Mensuality;
//import com.android.monee.data.model.Mensuality.MensualityState;
import com.android.monee.domain.BudgetService;
import com.android.monee.domain.MensGrp;
import com.android.monee.domain.MensGrp.MensGrpType;
import com.android.monee.domain.MensualityService;
import com.android.monee.domain.MensGrpOptimizer;
import com.android.monee.view.model.MensGrpHistoFollow;
import com.android.monee.view.model.MensualityHistoFollow;
import com.android.monee.R;


public class HistoSectionFragment extends Fragment {

	/**
	 * The fragment argument representing the section number for this
	 * fragment.
	 */
	public static final String ARG_SECTION_NUMBER = "section_number";

	private boolean optimized;
	private LayoutInflater inflater;
	private ExpandableListView expListView;
	private Menu menu;
	private DaoListener<Budget, Integer> budgetDaoListener; 
	
	public HistoSectionFragment() {
		setHasOptionsMenu(true);
	}
	
	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View root = inflater.inflate(R.layout.page_histo_follow,
				container, false);
		
		this.inflater = inflater;
		this.expListView = (ExpandableListView) root.findViewById(R.id.histo_follow_container);
		
		updateView();
		
		this.budgetDaoListener = new SimpleDaoListener<Budget, Integer>() {
			@Override
			public void onChange() {
				updateView();
			}
		};
		BudgetService.addBudgetDaoListener(this.budgetDaoListener);
		

		return root;
	}

	@Override
	public void onDestroyOptionsMenu() {
		super.onDestroyOptionsMenu();
		this.menu = null;
	}

	@Override
	public void onDestroyView() {
		super.onDestroyView();
		this.expListView = null;
		this.inflater = null;
		BudgetService.deleteBudgetDaoListener(this.budgetDaoListener);
		this.budgetDaoListener = null;
	}

	private void updateView() {
		List<MensGrp> mensGrps = MensGrp.calcMensGrps(MensGrpType.ALL);
		
		List<MensGrpHistoFollow> mensGrpHistoFollow = MensGrpHistoFollow
				.newCollection(mensGrps, getResources());

		BaseExpandableListAdapter adapter = new MensualityGroupAdapter(
				inflater, this.expListView, mensGrpHistoFollow);
		int scrollPosition = this.expListView.getFirstVisiblePosition();
		this.expListView.setAdapter(adapter);
		this.expListView.setSelection(scrollPosition);
		this.optimized = false;
		
		syncMenu();
	}

	private void optimizeView() {
		MensGrpOptimizer optimizer = new MensGrpOptimizer();
		List<MensGrp> optmzMensGroups = optimizer.optimize();
		Map<MensGrp, Float> optmzStats = optimizer.getOptmzStats();
		
		System.out
				.println("Optimization coherence : "
						+ (MensGrpOptimizer
								.checkCoherence(optmzMensGroups) ? "OK" : "KO"));
		
		List<Mensuality> allMensualities = MensGrp.toMensList(optmzMensGroups);
		//allMensualities.addAll(MensualityService.getDoneMensualities());
		
		List<MensGrpHistoFollow> mensGrpHistoFollow = MensGrpHistoFollow
				.newCollection(MensGrp.toMensGrps(allMensualities), optmzStats,
						getResources());
	
		BaseExpandableListAdapter adapter = new MensualityGroupAdapter(
				this.inflater, this.expListView, mensGrpHistoFollow);
		int scrollPosition = this.expListView.getFirstVisiblePosition();
		this.expListView.setAdapter(adapter);
		this.expListView.setSelection(scrollPosition);
		this.optimized = true;
		
		syncMenu();
		
	}
	
	private void syncMenu(){
		if(this.menu != null){
			MenuItem optimize = this.menu.findItem(R.id.histo_follow_action_optimize);
			optimize.setVisible(!this.optimized);
			MenuItem revert = this.menu.findItem(R.id.histo_follow_action_revert);
			revert.setVisible(this.optimized);
		}
	}
	
	@Override
	public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
		super.onCreateOptionsMenu(menu, inflater);
		
		inflater.inflate(R.menu.histo_follow, menu);
		this.menu = menu;
		
		syncMenu();
		
		System.out.println("onCreateOptionsMenu");
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		
		switch (item.getItemId()){
		case R.id.histo_follow_action_optimize:
			optimizeView();
			return true;
		case R.id.histo_follow_action_revert:
			updateView();
			return true;
		}
		return super.onOptionsItemSelected(item);
	}
}

class MensualityGroupAdapter extends BaseExpandableListAdapter{

	private List<MensGrpHistoFollow> mensGroups;
	private LayoutInflater inflater;
	private ExpandableListView exp;
	
	public MensualityGroupAdapter(LayoutInflater inflater, ExpandableListView exp, List<MensGrpHistoFollow> mensGroups){
		this.mensGroups = mensGroups;
		this.inflater = inflater;
		this.exp = exp;
	}
	
	private MensualityHistoFollow getMensuality(int groupPosition, int childPosition){
		MensGrpHistoFollow mensGroup =  mensGroups.get(groupPosition);
		return mensGroup.get(childPosition);
	}
	
	private MensGrpHistoFollow getMensualityGroup(int groupPosition){
		return this.mensGroups.get(groupPosition);
	}
	
	@Override
	public Object getChild(int groupPosition, int childPosition) {
		return getMensuality(groupPosition, childPosition);
	}

	@Override
	public long getChildId(int groupPosition, int childPosition) {
		return System.identityHashCode(getMensuality(groupPosition, childPosition));
	}

	@Override
	public View getChildView(int groupPosition, int childPosition,
			boolean isLastChild, View convertView, ViewGroup parent) {
		
		MensualityHistoFollow mens = getMensuality(groupPosition, childPosition);
		
		View root = this.inflater.inflate(R.layout.fragment_histo_follow_mensuality, parent, false);
		
		TextView nameTV = (TextView) root.findViewById(R.id.histo_follow_mensuality_name);
		TextView amountTV = (TextView) root.findViewById(R.id.histo_follow_mensuality_amount);
		
		nameTV.setText(mens.getMainLib());
		amountTV.setText(mens.getAmountLib());
		
		nameTV.getPaint().setStrikeThruText(mens.isDone());
		nameTV.setBackgroundColor(mens.getbBackgroundColor());
		nameTV.setTextColor(mens.getTextColor());
		amountTV.getPaint().setStrikeThruText(mens.isDone());
		amountTV.setBackgroundColor(mens.getbBackgroundColor());
		amountTV.setTextColor(mens.getTextColor());
		
		return root;
	}

	@Override
	public int getChildrenCount(int groupPosition) {
		return getMensualityGroup(groupPosition).size();
	}

	@Override
	public Object getGroup(int groupPosition) {
		return getMensualityGroup(groupPosition);
	}

	@Override
	public int getGroupCount() {
		return this.mensGroups.size();
	}

	@Override
	public long getGroupId(int groupPosition) {
		return System.identityHashCode(getMensualityGroup(groupPosition));
	}

	@Override
	public View getGroupView(final int groupPosition, boolean isExpanded,
			View convertView, ViewGroup parent) {
		
		final MensGrpHistoFollow mensGroup = getMensualityGroup(groupPosition);
		LinearLayout root = (LinearLayout) this.inflater.inflate(R.layout.fragment_histo_follow_mensuality_group, parent, false);
		
		LinearLayout cont = (LinearLayout)root.findViewById(R.id.histo_follow_mens_group_cont);
		TextView dateTV = (TextView) root.findViewById(R.id.histo_follow_mensuality_group_date);
		TextView amountTV = (TextView) root.findViewById(R.id.histo_follow_mensuality_group_amount);
		TextView deltaTV = (TextView) root.findViewById(R.id.histo_follow_mensuality_group_delta);
		
		cont.setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				if(exp.isGroupExpanded(groupPosition))
					exp.collapseGroup(groupPosition);
				else
					exp.expandGroup(groupPosition, true);
			}
		});
		
		if(!mensGroup.areAllDone()){
			cont.setOnLongClickListener(new View.OnLongClickListener() {
				@Override
				public boolean onLongClick(View v) {
					
					//TODO : si une une/des mesnsualités sont déjà cochées remplacer le libellé par
					//"...que le montant restant de..."
					AlertDialog.Builder builder = new AlertDialog.Builder(inflater.getContext());
					builder.setTitle(mensGroup.getDateLib());
					builder.setMessage("Veuillez confirmez que le montant de "+mensGroup.getNotProvAmountLib()+" a été provisionné.");
					builder.setNegativeButton("Annuler", null);
					builder.setPositiveButton("Confirmer", new OnClickListener() {
						@Override
						public void onClick(DialogInterface dialog, int which) {
							for(Mensuality mens : mensGroup){
								mens.setDone(true);
								MensualityService.insert(mens);	
							}
							notifyDataSetChanged();
						}
					});
	
					builder.show();
					return true;
				}
			});
		}
		
		dateTV.setText(mensGroup.getDateLib());
		amountTV.setText(mensGroup.getAmountLib());
		deltaTV.setText(mensGroup.getDeltaLib());
		
		dateTV.getPaint().setStrikeThruText(mensGroup.getStrike());
		dateTV.setTextColor(mensGroup.getTextColor());
		amountTV.getPaint().setStrikeThruText(mensGroup.getStrike());
		amountTV.setTextColor(mensGroup.getTextColor());
		deltaTV.setTextColor(mensGroup.getDeltaColor());
		
		cont.setBackgroundDrawable(mensGroup.getBackground());
		
		return root;
	}

	@Override
	public boolean hasStableIds() {
		return true;
	}

	@Override
	public boolean isChildSelectable(int groupPosition, int childPosition) {
		return true;
	}
	
}